<?php
/*
 *
 * @package MoltX
 * @author $Author$
 * @version $Id$
 * @link $URL$
 * @copyright Copyright (c) 2005-2010, Matthew Oltendorf
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 *
 */

/*
 * @ignore
 */
if ( ! defined ( 'blink' ) )
{
	// Access denied.
	header ( 'HTTP/1.1 403 Forbidden' );
	echo '403 - Forbidden';

	exit;
}

/*
 * Handler class
 * @package Blink
 *
 * Factory
 */
final class blink_handler
{
	public	$active,
			$rooms,
			$sock;

	/*
	 * Constructor function
	 *
	 * @return null
	 */
	public function __construct ( $sock, $rooms )
	{
		$this -> active = count ( $rooms );
		$this -> rooms = $rooms;
		$this -> sock = $sock;

		return null;
	}
}

/*
 * Room class
 * @package Blink
 *
 * Factory
 */
final class blink_room
{
	public	$index,
			$sock;

	/*
	 * Constructor function
	 *
	 * @param string $index the room identifier.
	 *
	 * @return null
	 */
	public function __construct ( $index )
	{
		$this -> index = $index;

		return null;
	}

	/*
	 * Close function
	 *
	 * Closes the room server.
	 *
	 * @return null
	 */
	public function close ( )
	{
		try
		{
			$server = blink_storage :: connect ( $this -> sock );
			$server -> send ( serialize ( array ( 'actions' => 'close' ) ) );
			$server -> close ( );
		}
		catch ( Exception $exception )
		{
			// Room server must be down. Ignore.
		}

		return null;
	}

	/*
	 * Spawn room function
	 *
	 * Spawns a room.
	 *
	 * @para blink_handler $handler the handler to use to spawn the room,
	 *		instead of attempting to spawn it locally.
	 *
	 * @return boolean
	 */
	public function ping ( )
	{
		$server = blink_storage :: connect ( $this -> sock );
		$server -> send ( serialize ( array ( 'actions' => 'ping' ) ) );
		$response = $server -> get ( );
		$server -> close ( );

		try
		{
			$data = unserialize ( $response );
		}
		catch ( Exception $exception )
		{
			return false;
		}

		return ! empty ( $data [ 'ping' ] );
	}

	/*
	 * Spawn room function
	 *
	 * Spawns a room.
	 *
	 * @para blink_handler $handler the handler to use to spawn the room,
	 *		instead of attempting to spawn it locally.
	 *
	 * @return boolean
	 */
	public function spawn ( $handler = null )
	{
		if ( $handler )
		{
			// @todo: spawn room using remote handler.
		}
		else
		{
			// Spawn room server.
			blink :: spawn ( 'room', $this -> index );

			$this -> sock = 'unix://' . blink_storage . '/socket/' . $this -> index . '.room.sock';
		}

		return true;
	}

	/*
	 * Validate function
	 *
	 * Validates a room identifier.
	 *
	 * @return boolean
	 */
	public static function validate ( $room )
	{
		if ( ! is_string ( $room ) )
		{
			return false;
		}

		static $regex = '/^[0-9a-zA-Z_-]+$/';

		return (boolean) preg_match ( $regex, $room );
	}
}
